﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Markup;
using XamlDom.Parser;
using XamlDom.Runtime;

namespace XamlDom.Reflector
{
    public class XamlToObjReader
    {
        public XamlNode _rootNode;

        public UIElement RootView
        {
            get
            {
                return _rootNode.Instance as UIElement;
            }
        }

        private object GetInstanceFromElementNode(XamlNode node)
        {
            Type instanceType = XamlTypeFinder.GetType(node.XmlNamespace, node.NodeName);
            object instance = ClrObjectRuntime.Instance.CreateInstance(instanceType, null);
            SetInstancePropertyValue(instance, node);
            return instance;
        }

        private void SetInstancePropertyValue(object instance,XamlNode node)
        {
            foreach (XamlAttribute attribute in node.Attributes)
            {
                string attributeName = attribute.PropertyName;
                string attributeValue = attribute.PropertyValue;
                ClrObjectRuntime.Instance.SetPropertyValue(instance, attributeName, attributeValue);
            }
        }

        public void BeginRead(XamlNode rootNode)
        {
            _rootNode = rootNode;
            ReadObject(rootNode, null);
        }

        internal void ReadObject(XamlNode rootNode, IAddChild parent)
        {
            object currentInstance = GetInstanceFromElementNode(rootNode);

            rootNode.Instance = currentInstance;

            if (parent != null)
            {
                parent.AddChild(currentInstance);
            }

            if (!rootNode.HasChildNode)
            {
                return;
            }

            int childCount = rootNode.ChildElementNodes.Count();

            if (currentInstance is IAddChild)
            {
                IAddChild container = (IAddChild)currentInstance;
                foreach (XamlNode childNode in rootNode.ChildElementNodes)
                {
                    ReadObject(childNode, container);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
    }
}
